﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace Sapiens.at.SharePoint.SQLM
{
    public class XmlData
    {
        public string ContentType { get; set; }
        public string ConnectionString { get; set; }
        public string SQLStatement { get; set; }
        public string[] InFieldParamMapping { get; set; }
        public string[] OutFieldParamMapping { get; set; }
        public string[] InFieldTypeMapping { get; set; }
        public string[] OutFieldTypeMapping { get; set; }
        public string CommandType { get; set; }
        public string SIUD { get; set; }
        public XmlData() { }
        public string ToXml()
        {
            return string.Format("<SQLMReceiverData>{0}</SQLMReceiverData>",
                string.Join("", this.GetType().GetProperties().Select(p => string.Format("<{0}>{1}</{0}>", p.Name, GetPropertyValue(p))).ToArray()));
        }
        public static XmlData Parse(string xml)
        {
            var xmlData = new XmlData();
            XmlDocument xDoc = new XmlDocument();
            xDoc.LoadXml(xml);
            foreach (XmlNode n in xDoc.FirstChild.ChildNodes)
            {
                object value = null;
                if (n.HasChildNodes && n.FirstChild.HasChildNodes)
                {
                    value = n.ChildNodes.Cast<XmlNode>().Select(node => DecodeFrom64(node.InnerText)).ToArray();
                }
                else value = DecodeFrom64(n.InnerText);
                var propInfo = xmlData.GetType().GetProperty(n.Name);
                if (propInfo != null && ((propInfo.PropertyType.IsArray && value is string[]) ||
                    !propInfo.PropertyType.IsArray && value is string))
                    propInfo.SetValue(xmlData, value, null);
            }
            return xmlData;
        }
        private string GetPropertyValue(System.Reflection.PropertyInfo p)
        {
            if (p.PropertyType.IsArray)
            {
                var value = p.GetValue(this, null);
                return string.Join("", ((string[])value).Select(v => string.Format("<Field>{0}</Field>", EncodeTo64(v))).ToArray());
            }
            else return EncodeTo64(Convert.ToString(p.GetValue(this, null)));
        }
        internal static string EncodeTo64(string toEncode)
        {
            byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
            string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
            return returnValue;
        }
        static public string DecodeFrom64(string encodedData)
        {
            byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
            string returnValue = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
            return returnValue;
        }

    }
}
